package com.autumn.mybatis.provider.builder;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Table;

import com.autumn.mybatis.metadata.EntityColumn;
import com.autumn.mybatis.metadata.EntityTable;
import com.autumn.mybatis.provider.IDbProvider;
import com.autumn.mybatis.provider.IDefinitionBuilder;
import com.autumn.util.EnvironmentConstants;
import com.autumn.util.ExceptionUtils;
import com.autumn.util.PackageUtils;
import com.autumn.util.StringUtils;

/**
 * 定义生成器抽象
 * 
 * @author 老码农
 *         <p>
 *         Description
 *         </p>
 * @date 2018-01-20 11:54:29
 */
public abstract class AbstractDefinitionBuilder extends AbstractBuilder implements IDefinitionBuilder {

	/**
	 * 
	 * @param dbProvider
	 */
	public AbstractDefinitionBuilder(IDbProvider dbProvider) {
		super(dbProvider);
	}

	@Override
	public final String createAnnotation(String text) {
		if (StringUtils.isNullOrBlank(text)) {
			return "";
		}
		return this.createAnnotation(StringUtils.splitNewLine(text.trim()));
	}

	/**
	 * 获取列类型
	 * 
	 * @param column
	 *            列
	 * @return
	 */
	public abstract String getColumnType(EntityColumn column);

	/**
	 * 创建表脚本集合
	 * 
	 * @param entityPackages
	 *            实体包集合
	 * @return
	 */
	@Override
	public String createTableScripts(String... entityPackages) {
		Set<Class<?>> entityTypeSet = new HashSet<>();
		if (entityPackages != null) {
			for (String entityPackage : entityPackages) {
				if (!StringUtils.isNullOrBlank(entityPackage)) {
					try {
						Set<Class<?>> pckClassSet = PackageUtils.getPackageAnnotationClass(entityPackage, Table.class,
								false, false, false);
						entityTypeSet.addAll(pckClassSet);
					} catch (IOException e) {
						ExceptionUtils.throwSystemException(e.getMessage(), e);
					}
				}
			}
		}
		String lineSeparator = EnvironmentConstants.LINE_SEPARATOR;
		StringBuilder sql = new StringBuilder();
		String rowSeparator = this.getScriptRowSeparator();
		int index = 0;
		for (Class<?> entityType : entityTypeSet) {
			EntityTable table = EntityTable.getTable(entityType);
			if (!table.isView()) {
				if (index > 0) {
					sql.append(lineSeparator);
					sql.append(lineSeparator);
					if (!StringUtils.isNullOrBlank(rowSeparator)) {
						sql.append(rowSeparator);
						sql.append(lineSeparator);
					}
				}
				sql.append(this.createAnnotation(this.getAnnotationLineSeparator()));
				sql.append(lineSeparator);
				sql.append(this.createAnnotation(
						"Table structure for " + table.getName() + " to " + table.getEntityClass().getName()));
				sql.append(lineSeparator);
				sql.append(this.createAnnotation(this.getAnnotationLineSeparator()));
				sql.append(lineSeparator);
				sql.append(this.createTableScript(table));
				index++;
			}
		}
		return sql.toString();
	}

	/**
	 * 创建表脚本
	 * 
	 * @param table
	 *            表
	 * @param tableName
	 *            表名称
	 * @return
	 */
	@Override
	public final String createTableScript(EntityTable table) {
		return this.createTableScript(table, null);
	}

	/**
	 * 注释分隔线
	 * 
	 * @return
	 */
	protected String getAnnotationLineSeparator() {
		return "--------------------------------------------------------";
	}

	/**
	 * 脚本行分隔
	 * 
	 * @return
	 */
	protected String getScriptRowSeparator() {
		return "";
	}

	/**
	 * 创建注释
	 * 
	 * @param texts
	 *            文本数组
	 * @return
	 */
	protected abstract String createAnnotation(String[] texts);

}
